#include <iostream>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
using namespace std;

static void Usage(const string &proc)
{
    cout << "\nUsage: " << proc << "pid signo\n" << endl;
}

void catchSig(int signo)
{
    cout << "获取到一个信号,信号编号是: " << signo << endl;
    exit(1);
}

int main(int argc, char *argv[])
{
    // 4.软件条件
    // alarm(1);
    // int cnt = 0;
    // while(true)
    // {
    //     cout << "cnt: " << cnt++ << endl;
    // }

    // 3.硬件异常产生信号
    // 信号产生,不一定非得用户显示的发送
    // signal(11, catchSig);
    // while (true)
    // {
    //     cout << "我正在运行中..." << endl;
    //     sleep(1);
    //     // 收到信号,不一定会引起进程退出,没有退出有可能还会被调度
    //     // cpu内部的寄存器只有一份,但是寄存器中的内容,属于当前进程的上下文
    //     // 没有能力或者动作修正这个问题
    //     // 当进程被切换的时候,就有无数次状态寄存器被保存会恢复的过程
    //     // 所以每一次恢复的时候,就让OS识别到了cpu内部的状态寄存器中的溢出标志位是1
    //     int a = 10;
    //     a /= 0; // 为什么除0会终止进程 -> 当前进程会收到来自操作系统的信号,SIGFPE
    //     // OS如何得知要给当前进程发送8号信号 -> cpu会异常

    //     int *p = nullptr;
    //     *p = 100;//为什么野指针会奔溃 -> 11号信号
    //     // OS如何知道 -> 硬件MMU异常
    // }

    // 2.系统调用向目标进程发送信号
    // kill() 可以向任意进程发送任意信号
    // raise() 给自己发送任意的信号
    // abotr() 给自己发送指定的信号SIGABRT

    // 关于信号处理的行为的理解: 有很多的情况,进程收到大部分的信号,默认处理动作都是终止进程
    // 信号的意义: 信号的不同,代表不同的事件,但是对事件发生之后的处理动作可以一样

    // int cnt = 0;
    // while(cnt <= 10)
    // {
    //     printf("cnt: %d\n", cnt++);
    //     sleep(1);
    //     // if(cnt >=5) raise(3);
    //     if(cnt >=5) abort();
    // }

    // if(argc != 3)
    // {
    //     Usage(argv[0]);
    //     exit(1);
    // }
    // pid_t pid = atoi(argv[1]);
    // int signo = atoi(argv[2]);
    // int n = kill(pid, signo);// 向进程发送信号
    // if(n != 0)
    // {
    //     perror("kill");
    // }

    // 发送信号
    // 1.通过键盘发送信号 -> (ctrl + c 信号2) -> (ctrl + \ 信号3)
    // while(true)
    // {
    //     cout << "hello world\n" << endl;
    //     sleep(1);
    // }
    return 0;
}